锁管理
最近更新时间: 2024-10-17 17:10:00
LOCK table 可获取表级锁,该语句只能在事务块中使用,没有 UNLOCK table 语句,事务结束时锁将自动释放。如果使用LOCK 命令对表进行加锁,缺省为最严格的模式 ACCESS EXCLUSIVE。
v3=# begin;
BEGIN
v3=# lock table t10;
LOCK TABLE
v3=# select relation::regclass,mode from pg_locks;
relation | mode
----------+---------------------
t10 | AccessExclusiveLock
表级锁
ACCESS SHARE
SELECT 命令在被引用的表上获得一个这种模式的锁。通常,任何只读取表而不修改它的查询都将获得这种锁模式。
ROW SHARE
SELECT FOR UPDATE 和 SELECT FOR SHARE 命令在目标表上取得一个这种模式的锁 (加上在被引用但没有选择 FOR UPDATE/FOR SHARE 的任何其他表上的 ACCESS SHARE 锁)。
ROW EXCLUSIVE
命令 UPDATE、DELETE 和 INSERT 在目标表上取得这种锁模式(加上在任何其他被引用表上的 ACCESS SHARE 锁)。通常,这种锁模式将被任何修改表中数据的命令取得。
SHARE UPDATE EXCLUSIVE
由 VACUUM(不带 FULL)、ANALYZE、CREATE INDEX CONCURRENTLY、CREATE STATISTICS 和 ALTER TABLE VALIDATE 以及其他 ALTER TABLE 的变体获得。
SHARE
由 CREATE INDEX(不带 CONCURRENTLY)取得。
SHARE ROW EXCLUSIVE
由 CREATE COLLATION、CREATE TRIGGER 和很多 ALTER TABLE 的很多形式所获得。
EXCLUSIVE
由 REFRESH MATERIALIZED VIEW CONCURRENTLY 获得。
ACCESS EXCLUSIVE
由 ALTER TABLE、DROP TABLE、TRUNCATE、REINDEX、CLUSTER、VACUUM FULL 和 REFRESH MATERIALIZED VIEW(不带 CONCURRENTLY)命令获取。ALTER TABLE 的很多形式也在这个层面上获得锁(见 ALTER TABLE)。这也是未显式指定模式的 LOCK TABLE 命令的默认锁模式。
冲突的锁模式
锁之间会互相阻塞、冲突。
请求的锁模式 | 当前的锁模式 | 当前的锁模式 | 当前的锁模式 | 当前的锁模式 | 当前的锁模式 | 当前的锁模式 | 当前的锁模式 | 当前的锁模式 |
---|---|---|---|---|---|---|---|---|
- | ACCESSSHARE | ROWSHARE | ROWEXCLUSIVE | SHAREUPDATE EXCLUSIVE | SHARE | SHAREROW EXCLUSIVE | EXCLUSIVE | ACCESSEXCLUSIVE |
ACCESS SHARE | - | - | - | - | - | - | - | X |
ROW SHARE | - | - | - | - | - | - | X | X |
ROW EXCLUSIVE | - | - | - | - | X | X | X | X |
SHARE UPDATE EXCLUSIVE | - | - | - | X | X | X | X | X |
SHARE | - | - | X | X | - | X | X | X |
SHARE ROW EXCLUSIVE | - | - | X | X | X | X | X | X |
EXCLUSIVE | - | X | X | X | X | X | X | X |
ACCESS EXCLUSIVE | X | X | X | X | X | X | X | X |
除了表级锁以外,还有行级锁,行级锁不影响数据查询,它们只阻塞对同一行的写入者和加锁者。
死锁
TDSQL-A PostgreSQL版 中,并发执行的事务由于竞争同一个资源会导致死锁。要检查在一个数据库中所有被锁的对象,可以查看 pg_locks 系统视图。
显式锁定的使用可能会增加死锁的可能性,死锁是指两个(或多个)事务相互持有对方想要的锁。可以手动或者以其他方式结束其中一个事务来解决死锁的问题。
查询当前存在的锁:
select pid,relation::regclass,mode from pg_locks where relation<>'pg_locks'::regclass::oid;
pid | relation | mode
-----------+------------+-----------------
27577 | t4 | AccessShareLock
可通过系统视图 pg_locks 的 pid 字段和系统视图 pg_stat_activity 关联查询出当前的持有锁的事务信息。